#ifndef IO_READER_H
#define IO_READER_H
#include <QObject>
#include <QDateTime>
#include <QMutex>
#include "KgGlobalData.h"

#define DO_READ_CMD           0x01    // 查询DO继电器状态指令 
#define DI_READ_CMD           0x02    // 查询DI离散量输入（光耦)状态指令 
#define DO_CTRL_CMD           0x05    // 控制DO继电器的打开或关闭
#define DO_SET_CMD            0x0F    // 控制多个DO指令
#define MAX_HLKG_COUNT        6       // 汇流开关最多个数, 一般只有一个
#define MAX_GLKG_COUNT        12      // 隔离开关最多个数

typedef struct _SPcsSetCmd
{
	quint16 uaRegAddr;       //Modbus 寄存器地址
	float   fUserValue;      //需要下置的数据
	quint16 uaRegValue;      //转换后需要下置的数据
	quint16 sleepTime;
	//int     bEmsSet;
}SPcsSetCmd;


// IO读写类 added 2022-1-17
class IOReader : public QObject
{
	Q_OBJECT
    friend void updateDryDataToRtdb(DryCtrlThread *pThread);
	friend class DryCtrlThread;
public:
	IOReader(QObject *parent, QString strRtuName);
	~IOReader();
public:
	bool openSerialPort();
	void DealwithSetDoCmd(int devIndex, DryData &dryData);
	void AddSetCmd(quint16 uaRegAddr, quint16 uaRegValue, quint16 sleepTime);
	int readDevDIState(int devIndex, DryData &dryData, int &readByteCount);  // 读取DI1--DI6的状态并判断消防告警
	int readDevDOState(int devIndex, DryData &dryData);// 读取DO1--DO6的状态
	int setDevAllDoState(int devIndex, DryData &dryData);
	int readOtherData(int devAddr, quint16 regAddr, quint16 regCount);

	
	//控制第1个DO口是否闭合(是否需要分励脱扣)
	bool setDoStateHZ(int doIndex, quint16 usNeedHz);
	//控制第2个DO口是否闭合(是否需要分励脱)
	//bool setDoStateFZ(int doIndex, quint16 usNeedFz);
	//bool sendCtrlDoCmd(char doIndex, quint16 usSetVal);
	//控制BCMU的DO口
    //void setBankDoState(quint16 fireAlarm);

	int analyRtuDatagram(quint16 uaDevAddr, char* pRecDataBuf, int iLen, int regCount);
	int analySetSingleDatagram(quint16 uaDevAddr, char* pRecDataBuf, int iLen, quint16 usRegAddr, quint16 usRegVal);
	void dealwithConnFailed(int runCount);
	void readDIValue(quint16 runCount);
	
private:		
	void sendLog(int iLogType, const QString& strLog);
	int  readDevReplay(quint16 step, quint16 desiredLen);
    void printSendInfo(int iIndexStep, char* pSendBufData, int iLen);
    void printReceInfo(int iIndexStep, char* pSendBufData, int iLen);
	QString getMsgFromIndexStep(int iIndexStep);

	int formSetMultgram15(uchar uaAddr, quint16 usRegAddr, quint16 regCount, quint16 usRegVal, char* pSendDataBuf);
	int analySetMultDatagram15(uchar uaAddr,char* pRecDataBuf, int iLen, quint16 usRegAddr, quint16 regCount);
	
    int  getParamFromBuffer(char* pData, quint16& uiParamVal);
    int  getParamFromBuffer(char* pData, quint32& uiParamVal);
    int  addParam2Buffer(char* pData, quint16 uiParamVal);
	quint16 getUint16(float fVal);
	float  getRealVal(quint16 uVal, float rate);
	float  getRealVal(quint32 uVal, float rate);
	
private:
	QString    m_strRtuName;
	CXnSerial *m_pRtuClient; 
	bool       m_bRtuOpened;
	int        m_iDevIndex;
	
	// char m_devDiCount;        // 设备DI干结点总个数
	// char m_devDoCount;        // 设备DO干结点总个数

	char       m_pDataBuf[500];
	char       m_readData[250];

private:
	QList<SPcsSetCmd> m_dryCmdList;
	QMutex m_mutex;
};
#endif // IO_READER_H
